home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <process.h>
-
- #define FILE_NOT_FOUND 0x02 // Error Code //
- #define PATH_NOT_FOUND 0x03 // Error Code //
- #define ACCESS_DENIED 0x05 // Error Code //
- #define NOT_SAME_DEVICE 0x11 // Error Code //
- #define NO_FILES_LEFT 0x12 // Error Code //
- #define MOVE_FILE 0x5600 // Documented Call //
- #define SERVER_CALL 0x5D00 // Undocumented Call //
- #define CANONICAL_NAMES 0x60 // Undocumented Call //
- #define DOS_SERVICES 0x21 // INT 21h DOS services //
- #define SUCCESS 0 // Useful Boolean //
- #define CARRY_FLAG 1 // Carry flag bit position //
-
- #define COPYRIGHT "Released into Public Domain by Walt Myers, 1993. \
- CIS 76407,2235"
-
- void argument_error(void);
- void check_result(void);
- void clean_up(int a);
- void get_canonical_names(void);
- int move_file(void);
- void set_registers(void);
-
- struct source
-
- {
- char path[128];
- char canonical_path[128];
- } old;
-
- struct destination
-
- {
- char path[128];
- char canonical_path[128];
- } new;
-
- struct // This is the DOS parameter list for INT 21h, function 0x5D00 //
-
- {
- unsigned int ax;
- unsigned int bx;
- unsigned int cx;
- unsigned int dx;
- unsigned int si;
- unsigned int di;
- unsigned int ds;
- unsigned int es;
- unsigned int reserved;
- unsigned int computer_ID; // Set to 0h for current machine //
- unsigned int process_ID; // The PSP for this program //
-
- } DOS_parameter_list;
-
- unsigned int data_segment;
- unsigned int extra_segment;
- unsigned int ax;
- unsigned int canonical_ds,canonical_dx,canonical_es,canonical_di,flags;
- unsigned int relative_ds,relative_dx,relative_es,relative_di,flags;
- unsigned int relative_si;
- unsigned int psp;
-
- int result;
-
-
- void main(int argc, char **argv)
-
- {
- if (argc != 3) argument_error(); // Check arguments //
- (void)strcpy(old.path, argv[1]); // Copy in arguments //
- (void)strcpy(new.path, argv[2]); // Copy in arguments //
- set_registers(); // Initialize registers //
- get_canonical_names(); // Get true names //
- result = move_file(); // Move the file //
- clean_up(result); // Quit //
-
- } // End main //
-
-
- void argument_error(void)
-
- {
-
- puts("\nItems in [] are optional. All others are required.");
- puts("\nUsage is move [path]\\filename [path]\\filename");
- puts("Wildcards (?,*) are OK. Can't move to different drive.\n");
- puts(COPYRIGHT);
- exit(1);
-
- } // End function //
-
-
- void check_result(void)
-
- {
-
- if ((flags & CARRY_FLAG) == SUCCESS) return; // OK //
-
- switch(ax)
-
- {
- case (0x02):
-
- puts("Invalid source name");
- puts(COPYRIGHT);
- exit(1);
-
- case (0x03):
-
- puts("Invalid drive or malformed path");
- puts(COPYRIGHT);
- exit(1);
-
- default:
-
- printf("Error = %d getting canonical names\n", ax);
- puts(COPYRIGHT);
- exit(1);
-
-
- } // End switch //
-
- } // End function //
-
-
- void clean_up(int a)
-
- {
-
- _DS = data_segment; // Reset data segment //
- _ES = extra_segment; // Reset extra segment //
-
- switch(a) // Check result //
-
- {
-
- case SUCCESS:
- case NO_FILES_LEFT:
- puts("File(s) moved successfully");
- puts(COPYRIGHT);
- break;
-
- case FILE_NOT_FOUND:
- puts("File not found");
- puts(COPYRIGHT);
- exit(1);
-
- case PATH_NOT_FOUND:
- puts("Path not found");
- puts(COPYRIGHT);
- exit(1);
-
- case ACCESS_DENIED:
- puts("Root directory full, file already exists or \
- access denied.");
- puts(COPYRIGHT);
- exit(1);
-
- case NOT_SAME_DEVICE:
- puts("Must move to same drive");
- puts(COPYRIGHT);
- exit(1);
-
- default:
- printf("Unknown errorcode = %d\n", a);
- puts(COPYRIGHT);
-
- } // End switch //
-
- } // End function //
-
-
- void get_canonical_names(void)
-
- {
-
- /* For INT 21h, function 60h:
-
- Call with:
-
- AH: 60h
- DS:SI Pointer to ASCIZ relative path string or filename
- ES:DI Pointer to 128 byte buffer for ASCIZ canonical
- fully qualified name
-
- Returns:
- CF set on error
- AX error code
- 02h invalid source name
- 03h invalid or malformed path
-
- CF clear if successful
- AH 0h
- AL Destroyed
- Buffer filled with qualified name.
-
- */
-
- // Do the from, or the old, first //
-
- relative_ds = FP_SEG(old.path);
- relative_si = FP_OFF(old.path);
- canonical_es = FP_SEG(old.canonical_path);
- canonical_di = FP_OFF(old.canonical_path);
-
- _AH = CANONICAL_NAMES; // Load registers //
- _DS = relative_ds;
- _SI = relative_si;
- _ES = canonical_es;
- _DI = canonical_di;
-
- geninterrupt(DOS_SERVICES); // Get canonical names //
- check_result(); // Check result //
- flags = _FLAGS; // Load variable //
- ax = _AX; // Load variable //
-
- _DS = data_segment; // Reset _DS //
-
- // Do the to, or the new, next //
-
- relative_ds = FP_SEG(new.path);
- relative_si = FP_OFF(new.path);
- canonical_es = FP_SEG(new.canonical_path);
- canonical_di = FP_OFF(new.canonical_path);
-
- _AH = CANONICAL_NAMES; // Load registers //
- _DS = relative_ds;
- _SI = relative_si;
- _ES = canonical_es;
- _DI = canonical_di;
-
- geninterrupt(DOS_SERVICES); // Get canonical names //
- flags = _FLAGS; // Load variable //
- ax = _AX; // Load variable //
- check_result(); // Check result //
-
- _DS = data_segment; // Reset _DS //
-
- // Now that buffers are loaded, set up variables for move call //
-
- canonical_ds = FP_SEG(old.canonical_path); // Old canonical path //
- canonical_dx = FP_OFF(old.canonical_path);
-
- // Variables for the new path are set above (canonical_es,di) //
-
-
- } // End function //
-
-
- int move_file(void)
-
- {
-
- unsigned int ax;
-
- /* For moving files, it's INT 21h, function 5D00h (undocumented
- behavior with 5D00h lets you use wild cards. Using the
- documented function 56h doesn't permit the use of wild cards).
-
- Call with:
- AH 5Dh
- DS:DX Pointer to DOS parameter list where DPL
- contains all the necessary information for
- it's own call to INT 21h. So, fill the DPL
- with all the right information for a function
- 56h call.
-
- For a function 56h call:
-
- Call with:
- AH 56h
- DS:DX Pointer to ASCIZ old filespec
- ES:DI Pointer to ASCIZ new filespec
-
- Note: When invoked by function 5D00, (like we're doing here),
- both source and destination filespec must be canonical
- as returned by function 60h.
- */
-
-
-
- // Load the DOS parameter list //
-
- DOS_parameter_list.ax = MOVE_FILE; // Move file function //
- DOS_parameter_list.bx = _BX;
- DOS_parameter_list.cx = _CX;
- DOS_parameter_list.dx = canonical_dx; // Old path offset //
- DOS_parameter_list.si = _SI;
- DOS_parameter_list.di = canonical_di; // New path offset //
- DOS_parameter_list.ds = canonical_ds; // Old path segment //
- DOS_parameter_list.es = canonical_es; // New path segment //
- //DOS_parameter_list.reserved Comment out this one //
- DOS_parameter_list.computer_ID =0x0000;// Current system //
- DOS_parameter_list.process_ID = psp; // psp for this program //
-
- // Call the server interrupt which will call int 21 with the //
- // parameters listed above. //
-
- _DS = FP_SEG(&DOS_parameter_list); // Segment of DPL //
- _DX = FP_OFF(&DOS_parameter_list); // Offset of DPL //
- _AX = SERVER_CALL; // Server Call //
-
- geninterrupt(DOS_SERVICES); // Server Function Call //
-
- _DS = data_segment; // Reset data segment //
-
- ax = _AX; // Store register //
- flags =_FLAGS; // Save _FLAGS //
- result = (flags & CARRY_FLAG); // Get carry flag //
-
- if (result != SUCCESS) result = ax; // Load result variable //
-
- return(result);
-
- } // End function //
-
-
- void set_registers(void)
-
- {
-
- data_segment = _DS; // Save current segments //
- extra_segment= _ES; // Save current segments //
- psp = getpsp(); // Get psp //
-
- }